<template>
  <div class="app-container">
    <div class="filter-container">
      <el-input
        v-model="listQuery.name"
        :placeholder="$t('table.menu.name')"
        style="width: 200px;"
        class="filter-item"
        clearable
      />
      <flushBtn @handle="handleFilter" />
      <addBtn auth="sys:menu:add" @handle="handleBtn([5])" />
    </div>
    <el-table
      v-loading="listLoading"
      :data="treeTable"
      row-key="menuId"
      border
      fit
      :expand-row-keys="expandRow"
      highlight-current-row
      style="width: 100%;"
      :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
      :height="tableHeight"
    >
      <el-table-column
        :label="$t('table.id')"
        align="center"
        type="index"
        style="width:50px;"
        min-width="12%"
      >
        <template slot-scope="{row}">{{ row.menuId }}</template>
      </el-table-column>
      <el-table-column :label="$t('table.menu.name')" min-width="15%" align="center" prop="name">
        <template slot-scope="{row}">
          <span v-html="row.name" />
        </template>
      </el-table-column>
      <el-table-column :label="$t('table.menu.menuSign')" min-width="10%" align="center">
        <template slot-scope="{row}">
          <span>{{ row.menuSign }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('table.menu.url')" min-width="15%">
        <template slot-scope="{row}">
          <div v-if="row.url">
            <el-tag>{{ row.url }}</el-tag>
          </div>
        </template>
      </el-table-column>
      <el-table-column :label="$t('table.menu.perms')" min-width="20%" align="center">
        <template slot-scope="{row}">
          <span>{{ row.perms }}</span>
        </template>
      </el-table-column>

      <el-table-column :label="$t('table.menu.icon')" prop="icon" min-width="6%" align="center">
        <template slot-scope="{row}">
          <span v-if="row.icon &&row.icon.indexOf('el-icon')>-1">
            <i :class="row.icon" />
          </span>
          <span v-if="row.icon &&row.icon.indexOf('el-icon')==-1">
            <svg-icon :icon-class="row.icon" />
          </span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('table.menu.type')" min-width="6%" align="center">
        <template slot-scope="{row}">
          <span v-if="row.type==='0'" style="color:red;">{{ $t('table.menu.dir') }}</span>
          <span v-if="row.type==='1'" style="color:blue;">{{ $t('table.menu.menu') }}</span>
          <span v-if="row.type==='2'">{{ $t('table.menu.btn') }}</span>
        </template>
      </el-table-column>

      <el-table-column
        :label="$t('table.actions')"
        align="center"
        min-width="25%"
        class-name="small-padding fixed-width"
      >
        <template slot-scope="{row}">
          <groupBtn :auths="btnGroup" :param="row" @handle="handleBtn(arguments)" />
        </template>
      </el-table-column>
    </el-table>
    <el-dialog :title="$t(textMap[dialogStatus])" :visible.sync="dialogFormVisible">
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="temp"
        label-position="left"
        label-width="100px"
        style="width: 500px; margin-left:50px;"
      >
        <el-form-item :label="$t('table.menu.parent')+':'" prop="parentId">
          <el-input v-model="temp.menuId" style="display:none;" />
          <el-input v-model="temp.parentId" style="display:none;" />
          <el-input v-model="temp.parentName" disabled />
        </el-form-item>
        <el-form-item :label="$t('table.menu.name')" prop="name">
          <el-input v-model="temp.name" />
        </el-form-item>
        <el-form-item :label="$t('table.menu.menuSign')" prop="menuSign">
          <el-input v-model="temp.menuSign" />
        </el-form-item>
        <el-form-item :label="$t('table.menu.type')" prop="type">
          <el-select v-model="temp.type" class="filter-item" placeholder @change="showUrl">
            <el-option
              v-for="item in calendarTypeOptions"
              :key="item.key"
              :label="$t(item.display_name)"
              :value="item.key"
            />
          </el-select>
        </el-form-item>
        <el-form-item v-if="urlShow" :label="$t('table.menu.url')" prop="url">
          <el-input v-model="temp.url" />
        </el-form-item>
        <el-form-item :label="$t('table.menu.icon')" prop="icon">
          <div style="display:inline;">
            <el-input v-model="temp.icon" style="width:60%;" />
            <el-button
              style="width:40%;"
              type="success"
              icon="el-icon-setting"
              @click="showIcon"
            >选择图标</el-button>
          </div>
        </el-form-item>
        <el-form-item :label="$t('table.menu.perms')" prop="perms">
          <el-input v-model="temp.perms" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">{{ $t('table.cancel') }}</el-button>
        <el-button type="primary" @click="createData()">{{ $t('table.confirm') }}</el-button>
      </div>
    </el-dialog>

    <el-dialog :title="$t('table.menu.icon')" :visible.sync="iconVisible">
      <Icons />
    </el-dialog>
  </div>
</template>

<script>
import {
  fetchMenuList,
  updateMenu,
  findByMenuId,
  deleteByMenuId
} from '@/api/system'
import groupBtn from '@/components/buttonGroup/groupBtn'
import flushBtn from '@/components/buttonGroup/flushBtn'
import addBtn from '@/components/buttonGroup/addBtn'
import Icons from '@/views/icons/index'
const calendarTypeOptions = [
  { key: '0', display_name: 'table.menu.dir' },
  { key: '1', display_name: 'table.menu.menu' },
  { key: '2', display_name: 'table.menu.btn' }
]
export default {
  name: 'Menu',
  components: { groupBtn, flushBtn, addBtn, Icons },
  data() {
    return {
      tableHeight: window.innerHeight - 200,
      expandRow: [],
      btnGroup: [
        { id: 1, auth: 'sys:menu:add', name: 'table.add' },
        {
          id: 2,
          auth: 'sys:menu:edit',
          btnType: 'success',
          name: 'table.edit'
        },
        {
          id: 3,
          auth: 'sys:menu:delete',
          btnType: 'danger',
          name: 'table.delete'
        }
      ],
      tableData: [],
      list: [],
      listLoading: true,
      listQuery: {
        name: undefined
      },
      calendarTypeOptions,
      temp: {
        menuId: undefined,
        parentId: '',
        parentName: '',
        name: '',
        type: '1',
        url: '',
        perms: '',
        icon: '',
        menuSign: ''
      },
      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        update: 'table.menu.edit',
        create: 'table.menu.create'
      },
      rules: {
        name: [
          {
            required: true,
            message: this.$t('table.menu.nameRule'),
            trigger: 'blur'
          }
        ]
      },
      urlShow: false,
      downloadLoading: false,
      iconVisible: false
    }
  },
  computed: {
    treeTable: function() {
      var searchValue = this.listQuery.name
      if (searchValue) {
        const treeData = JSON.parse(JSON.stringify(this.tableData))
        const handleTreeData = this.handleTreeData(treeData, searchValue)
        // this.setExpandRow(handleTreeData)
        // this.expandRow = this.expandRow.join(',').split(',')
        return handleTreeData
      }
      return this.tableData
    }
  },
  watch: {
    treeTable(old, newVal) {
      this.setExpandRow(newVal)
      this.expandRow = this.expandRow.join(',').split(',')
    }
  },
  created() {
    this.getList()
  },
  methods: {
    showUrl() {
      console.log(this.temp.type)
      if (this.temp.type === 1) {
        this.urlShow = true
      }
    },
    showIcon() {
      this.iconVisible = true
    },
    handleFilter() {
      this.getList()
    },
    getList() {
      this.listLoading = true
      fetchMenuList({}).then(response => {
        this.list = response.content
        this.createList()
        setTimeout(() => {
          this.listLoading = false
        }, 1000)
      })
    },
    resetTemp() {
      this.temp = {
        menuId: undefined,
        parentId: '',
        parentName: '',
        name: '',
        type: '1',
        url: '',
        perms: '',
        icon: '',
        menuSign: ''
      }
    },
    createData() {
      this.$refs['dataForm'].validate(valid => {
        if (valid) {
          updateMenu(this.temp).then(data => {
            if (this.temp.menuId) {
              this.list.forEach(item => {
                if (item.menuId === this.temp.menuId) {
                  item.name = this.temp.name
                  item.url = this.temp.url
                  item.perms = this.temp.perms
                  item.icon = this.temp.icon
                  item.type = this.temp.type
                  item.menuSign = this.temp.menuSign
                }
              })
            } else {
              this.temp.menuId = data.content.menuId
              this.list.push(this.temp)
            }
            this.createList()
            this.dialogFormVisible = false
            this.$message({
              type: 'success',
              message: data.msg
            })
          })
        }
      })
    },
    createList: function() {
      const jsonStr = {}
      JSON.parse(JSON.stringify(this.list)).forEach(item => {
        jsonStr[item.menuId] = item
      })
      const root = { menuId: 0, name: this.$t('table.menu.root') }
      this.createListRoot(jsonStr, root)
      const rootList = []
      rootList.push(root)
      this.tableData = root.children
      // this.setExpandRow(this.tableData)
      //  this.expandRow = this.expandRow.join(',').split(',')
    },
    createListRoot: function(jsonStr, root) {
      if (Object.keys(jsonStr).length > 0) {
        for (const key in jsonStr) {
          const item = jsonStr[key]
          if (item.parentId === root.menuId) {
            if (!root.children) {
              root.children = []
            }
            // item.name = '<span style="color:red;">' + item.name + '</span>'
            root.children.push(item)
            delete jsonStr[key]
            this.createListRoot(jsonStr, item)
          }
        }
      }
    },
    /** 按钮回调 **/
    handleBtn: function(param) {
      const id = param[0]
      const row = param[1]
      this.resetTemp()
      if (id === 1) {
        this.resetTemp()
        this.temp.parentId = row.menuId
        this.temp.parentName = row.name
        this.dialogStatus = 'create'
        this.dialogFormVisible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      } else if (id === 2) {
        findByMenuId(row.menuId).then(data => {
          const content = data.content
          this.temp = JSON.parse(JSON.stringify(content))
          const parentId = content.parentId
          if (parentId === 0) {
            this.temp.parentName = this.$t('table.menu.root')
          } else {
            const parent = this.list.filter(item => item.menuId === parentId)
            this.temp.parentName = parent[0].name
          }

          delete this.temp.createDate
          this.dialogFormVisible = true
          this.$nextTick(() => {
            this.$refs['dataForm'].clearValidate()
          })
        })
      } else if (id === 3) {
        this.$confirm('此操作将删除及其子菜单, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
          .then(() => {
            deleteByMenuId(row.menuId).then(data => {
              this.list.splice(
                this.list.findIndex(item => item.menuId === row.menuId),
                1
              )
              this.createList()
              this.$message({
                type: 'success',
                message: '删除成功!'
              })
            })
          })
          .catch(() => {
            this.$message({
              type: 'info',
              message: '已取消删除'
            })
          })
      } else if (id === 5) {
        this.resetTemp()
        this.temp.parentId = 0
        this.temp.parentName = this.$t('table.menu.root')
        this.dialogStatus = 'create'
        this.dialogFormVisible = true
        this.$nextTick(() => {
          this.$refs['dataForm'].clearValidate()
        })
      }
    },
    //  树形表格过滤
    handleTreeData(treeData, searchValue) {
      if (!treeData || treeData.length === 0) {
        return []
      }
      const array = []
      for (let i = 0; i < treeData.length; i++) {
        let match = false
        // for (let pro in treeData[i]) {
        //   if (typeof treeData[i][pro] == 'string') {
        //     match |= treeData[i][pro].includes(searchValue)
        //     if (match) {
        //       var reg = new RegExp('(' + searchValue + ')', 'g')
        //       var str = treeData[i][pro]
        //       var newstr = str.replace(reg, '<font color=red>$1</font>')
        //       treeData[i][pro]=newstr
        //       break
        //     }
        //   }
        // }
        if (treeData[i].name.includes(searchValue)) {
          match = true
          var reg = new RegExp('(' + searchValue + ')', 'g')
          var str = treeData[i].name
          var newstr = str.replace(reg, '<font color=red>$1</font>')
          treeData[i].name = newstr
        }
        if (
          this.handleTreeData(treeData[i].children, searchValue).length > 0 ||
          match
        ) {
          array.push({
            ...treeData[i],
            children: this.handleTreeData(treeData[i].children, searchValue)
          })
        }
      }
      return array
    },
    // 将过滤好的树形数据展开
    setExpandRow(handleTreeData) {
      if (handleTreeData.length) {
        for (const i of handleTreeData) {
          this.expandRow.push(i.menuId)
          if (i.children && i.children.length) {
            this.setExpandRow(i.children)
          }
        }
      }
    }
  }
}
</script>